package com.mpb.prj.practice;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Arguements input fasta filename, parameter filename and spectrum filename
 * fasta filename must and should be unique
 * 
 */
public class JPLGenerateXml {

	private String dataFolderPath;
	private String xtandemFolderPath;

	public String getXtandemFolderPath() {
		return xtandemFolderPath;
	}

	public void setXtandemFolderPath(String xtandemFolderPath) {
		this.xtandemFolderPath = xtandemFolderPath;
	}

	public String getDataFolderPath() {
		return dataFolderPath;
	}

	public void setDataFolderPath(String dataFolderPath) {
		this.dataFolderPath = dataFolderPath;
	}

	public JPLGenerateXml() {
		dataFolderPath = "";
		xtandemFolderPath = "";
	}

	/**
	 * This function is for to run XTandem inputfile.
	 * 
	 * @param taxonamyFile
	 * @param parameterFile
	 * @param spectrumFile
	 * @throws IOException
	 * @throws SAXException
	 * @throws ParserConfigurationException
	 * @throws TransformerException
	 */
	public void generateXtandemInputXml(String taxonamyFile,
			String parameterFile, String spectrumFile, String paramsFile)
			throws SAXException, IOException, ParserConfigurationException,
			TransformerException {

		generateTaxonamyXml("uniprot_human_withReverse.fasta", "taxonamy.xml");

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbf.newDocumentBuilder();
		Document doc = dBuilder.newDocument();
		String aInputFile = "new_input.xml";
		String outputFile = "new_output.xml";

		Element root = doc.createElement("bioml");
		doc.appendChild(root);

		Element node = doc.createElement("note");

		node.setAttribute("label", "list path, default parameters");
		node.setAttribute("type", "input");
		node.setTextContent(getXtandemFolderPath() + "/" + parameterFile);
		root.appendChild(node);

		node = doc.createElement("note");
		node.setAttribute("label", "list path, taxonomy information");
		node.setAttribute("type", "input");
		node.setTextContent(getXtandemFolderPath() + "/" + taxonamyFile);
		root.appendChild(node);

		node = doc.createElement("note");
		node.setAttribute("label", "protein, taxon");
		node.setAttribute("type", "input");
		node.setTextContent("human");
		root.appendChild(node);

		node = doc.createElement("note");
		node.setAttribute("label", "spectrum, path");
		node.setAttribute("type", "input");
		node.setTextContent(getDataFolderPath() + "/" + spectrumFile);
		root.appendChild(node);

		node = doc.createElement("note");
		node.setAttribute("label", "output, path");
		node.setAttribute("type", "input");
		node.setTextContent(getDataFolderPath() + "/" + outputFile);
		root.appendChild(node);

		if(paramsFile != null && paramsFile.length() > 0)
			addAdditionalParams(doc, root, paramsFile);

		// Creating xml file
		// set up a transformer
		TransformerFactory transfac = TransformerFactory.newInstance();
		Transformer trans = transfac.newTransformer();
		trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		trans.setOutputProperty(OutputKeys.INDENT, "yes");

		// create string from xml tree
		StringWriter sw = new StringWriter();
		StreamResult result = new StreamResult(sw);
		DOMSource source = new DOMSource(doc);
		trans.transform(source, result);
		String xmlString = sw.toString();

		FileWriter fw = new FileWriter(new File(getDataFolderPath() + "/"
				+ aInputFile));
		fw.write(xmlString);
		fw.flush();
		fw.close();

	}

	private void addAdditionalParams(Document document, Element root, String paramsFile)
			throws ParserConfigurationException, SAXException, IOException {

		File file = new File(paramsFile);
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(file);
		doc.getDocumentElement().normalize();
		
		NodeList nodeLst = doc.getElementsByTagName("note");

		for (int s = 0; s < nodeLst.getLength(); s++) {
			
			root.appendChild(document.importNode(nodeLst.item(s),true));
		}
	}

	public void generateXtandemInputXml(String taxonamyFile,
			String parameterFile, String spectrumFile) throws SAXException,
			IOException, ParserConfigurationException, TransformerException {
		generateXtandemInputXml(taxonamyFile, parameterFile, spectrumFile, null);
	}

	public void generateTaxonamyXml(String fastaFile, String taxonamyFile)
			throws ParserConfigurationException, TransformerException,
			IOException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbf.newDocumentBuilder();
		Document doc = dBuilder.newDocument();
		Element root = doc.createElement("bioml");
		root.setAttribute("label", "x! taxon-to-file matching list");
		doc.appendChild(root);

		Element taxon = doc.createElement("taxon");
		taxon.setAttribute("label", "human");
		root.appendChild(taxon);

		Element file = doc.createElement("file");
		file.setAttribute("format", "peptide");
		file.setAttribute("URL", getXtandemFolderPath() + "/" + fastaFile);
		taxon.appendChild(file);

		TransformerFactory transfac = TransformerFactory.newInstance();
		Transformer trans = transfac.newTransformer();
		trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		trans.setOutputProperty(OutputKeys.INDENT, "yes");

		// create string from xml tree
		StringWriter sw = new StringWriter();
		StreamResult result = new StreamResult(sw);
		DOMSource source = new DOMSource(doc);
		trans.transform(source, result);
		String xmlString = sw.toString();
		FileWriter fw = new FileWriter(new File(getXtandemFolderPath() + "/"
				+ taxonamyFile));
		fw.write(xmlString);
		fw.flush();
		fw.close();

	}

}
